#if !defined(ximera_math_matrix3_hpp)
#define ximera_math_matrix3_hpp

// -----------------------------------------------------------

#include <ximera/types.hpp>
#include <ximera/math/util.hpp>
#include <ximera/math/vector3.hpp>
#include <algorithm>

namespace ximera { namespace math
{
    class XIMERA_API Matrix3
    {
    public:
        Matrix3();
        Matrix3(bool zero);
        Matrix3(Real const array[3][3]);
        Matrix3(Real m00, Real m01, Real m02,
                Real m10, Real m11, Real m12,
                Real m20, Real m21, Real m22);
        
        Real* operator[](int row);
        Real const* operator[](int row) const;

        Real& operator()(int row, int col);
        Real operator()(int row, int col) const;

        void makeIdentity();
        void makeZero();

        Real* asArray();
        Real const* asArray() const;

        Matrix3& transpose();
        Matrix3 asTranspose() const;

        Matrix3& inverse();
        Matrix3 asInverse() const;

        Matrix3& add(Matrix3 const& matrix);
        Matrix3& subtract(Matrix3 const& matrix);
        Matrix3& multiply(Matrix3 const& matrix);

        Matrix3& operator+=(Matrix3 const& rhs);
        Matrix3& operator-=(Matrix3 const& rhs);
        Matrix3& operator*=(Real rhs);
        Matrix3& operator/=(Real rhs);

        static Matrix3 const ZERO;
        static Matrix3 const IDENTITY;

    private:
        union {
            Real _matrix[3][3];
            Real _array[3*3];
        };
    };

    Matrix3 operator*(Matrix3 const& lhs, Matrix3 const& rhs);

    Vector3 operator*(Vector3 const& lhs, Matrix3 const& rhs);
    Vector3 operator*(Matrix3 const& lhs, Vector3 const& rhs);

    Matrix3 operator*(Matrix3 const& lhs, Real rhs);
    Matrix3 operator*(Real lhs, Matrix3 const& rhs);

    Matrix3 operator/(Matrix3 const& lhs, Real rhs);
}}

#include <ximera/math/inline/matrix3.inl>

// -----------------------------------------------------------

#endif
